package server;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

import model.WavToInstanceParser;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import weka.core.Instance;
import classification.Classifier;

public class RestHandler extends AbstractHandler {

	// private static final MultipartConfigElement MULTI_PART_CONFIG = new
	// MultipartConfigElement(
	// System.getProperty("java.io.tmpdir"));

	private static final MultipartConfigElement MULTI_PART_CONFIG = new MultipartConfigElement(
			System.getProperty("user.dir"));

	private static String FILE_NAME = "TMP_VWG";
	public static String GET_DATA = "GET";
	public static String POST_DATA = "POST";
	public static String KEY = Double
			.toString(Math.random() * Double.MAX_VALUE);

	private Classifier classifier = null;

	private SecureRandom random = new SecureRandom();

	public RestHandler(Classifier c) {
		this.classifier = c;
	}

	private static Logger LOGGER = Logger.getLogger(RestHandler.class
			.toString());

	public void handle(String target, Request baseRequest,
			HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {

		if (request.getContentType() != null
				&& request.getContentType().startsWith("multipart/form-data")) {
			baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT,
					MULTI_PART_CONFIG);
			request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT,
					MULTI_PART_CONFIG);
		}

		Map<String, String[]> params = request.getParameterMap();

		if (params.containsKey("type")) {

			String type = params.get("type")[0];

			if (type.equals(POST_DATA)) {
				try {
					getData(request, response, params, type);
				} catch (UnsupportedAudioFileException e) {
					e.printStackTrace();
				}
			}

		}

	}

	private void getData(HttpServletRequest request,
			HttpServletResponse response, Map<String, String[]> params,
			String type) throws IOException, ServletException,
			UnsupportedAudioFileException {

		response.setContentType("text/plain; charset=UTF-8");

		String classify = "ERROR";

		for (Part part : request.getParts()) {

			FILE_NAME = new BigInteger(130, random).toString(32) + ".wav";
			part.write(FILE_NAME);

			String absoluteFileNameToClassify = System.getProperty("user.dir")
					+ File.separator + FILE_NAME;

		//	 for(int i = 1; i < 4; i++) {
			Instance i1 = WavToInstanceParser.parseToInstance(
					absoluteFileNameToClassify, Classifier.getInstances(),
					true, 1);

			try {
				classify = classifier.classify(i1);
				System.out.println(classify);

			} catch (Exception e) {
				e.printStackTrace();
			}
	//		 }
			
			File file1 = new File(System.getProperty("user.dir")
					+ File.separator + FILE_NAME);

//			if (file1.delete()) {
//				System.out.println(file1.getName() + " is deleted!");
//			} else {
//				System.out.println("Delete operation is failed.");
//			}
//
//			file1.deleteOnExit();
		//	part.delete();
		}

		try {
			LOGGER.log(Level.INFO, "Obtainig data." + "\t" + type);
			response.getWriter().println(classify);
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(HttpServletResponse.SC_FORBIDDEN);
			response.getWriter().println(
					"Nie można odczytać pliku - brak uprawnień");
		}

		((Request) request).setHandled(true);

	}

	private void changeSampleRate(String src, String dest, int sampleRate)
			throws IOException, UnsupportedAudioFileException {

		int fTargetSampleRate = sampleRate;
		File sourceFile = new File(src);
		File targetFile = new File(dest);

		AudioFileFormat sourceFileFormat = AudioSystem
				.getAudioFileFormat(sourceFile);
		AudioFileFormat.Type targetFileType = sourceFileFormat.getType();

		AudioInputStream sourceStream = null;
		sourceStream = AudioSystem.getAudioInputStream(sourceFile);
		AudioFormat sourceFormat = sourceStream.getFormat();

		float fTargetFrameRate = fTargetSampleRate;

		AudioFormat targetFormat = new AudioFormat(sourceFormat.getEncoding(),
				fTargetSampleRate, sourceFormat.getSampleSizeInBits(),
				sourceFormat.getChannels(), sourceFormat.getFrameSize(),
				fTargetFrameRate, sourceFormat.isBigEndian());

		AudioInputStream targetStream = AudioSystem.getAudioInputStream(
				targetFormat, sourceStream);

		int nWrittenBytes = AudioSystem.write(targetStream, targetFileType,
				targetFile);

	}

}
